#include "GraphicsDevice.h"
#include "Color.h"

#include <SDL_opengl.h>
#include <gl\GLU.h>

using namespace EPOC;

GraphicsDevice::GraphicsDevice()
{
	dirtyFlags = 0;

	SetSynchronizeWithVerticalRetrace(true);
	SetFullscreen(true);
	SetPreferredBackBufferWidth(800);
	SetPreferredBackBufferHeight(600);
	SetOpenGL(true);
	SetWindowPositionMode(WINDOWPOSITIONMODE::CENTERED);

	Initialize();
}

GraphicsDevice::~GraphicsDevice()
{
}

void GraphicsDevice::Initialize()
{
	
	int w = GetPreferredBackBufferWidth();
	int h = GetPreferredBackBufferHeight();

	Uint32 windowFlags = SDL_WINDOW_SHOWN;
	if(IsOpenGLEnabled())
		windowFlags |= SDL_WINDOW_OPENGL;
	if(IsFullscreenEnabled())
		windowFlags |= SDL_WINDOW_FULLSCREEN;
	else if(IsFullscreenDesktopEnabled())
		windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;

	int x,y;
	GetWindowPosition(x, y);

	if(windowPositionMode == WINDOWPOSITIONMODE::UNDEFINED)
	{
		x = SDL_WINDOWPOS_UNDEFINED;
		y = SDL_WINDOWPOS_UNDEFINED;
	}
	else if(windowPositionMode == WINDOWPOSITIONMODE::CENTERED)
	{
		x = SDL_WINDOWPOS_CENTERED;
		y = SDL_WINDOWPOS_CENTERED;
	}


	window = SDL_CreateWindow("EPOC Origins", x, y, w, h,  windowFlags);
	if(window == nullptr)
	{
		//TODO: We got no window, use SDL_GetError();
		_asm int 3;
	}


	renderer = SDL_CreateRenderer(window, 1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
	if(renderer == nullptr)
	{
		//TODO: We got no renderer, use SDL_GetError();
		_asm int 3;
	}

    SDL_GetRendererInfo(renderer, &rendererInfo); 
	
	/*TODO: Check that we have OpenGL */
    if ((rendererInfo.flags & SDL_RENDERER_ACCELERATED) == 0 || (rendererInfo.flags & SDL_RENDERER_TARGETTEXTURE) == 0) 
	{
        /*TODO: Handle this. We have no render surface and not accelerated. */
		_asm int 3;
    }
}

void GraphicsDevice::SetWindowPosition(int x, int y)					
{ 
	windowPositionX = x;
	windowPositionY = y;

	SetDirty(WINDOWSTATE);
}

void GraphicsDevice::GetWindowPosition(int &x, int &y)
{
	x = windowPositionX;
	y = windowPositionY;
}


void GraphicsDevice::ApplyChanges()
{
	// Is something dirty
	if(dirtyFlags == 0)
		return;

	//TODO: Check all flags an act accordingly

}


void GraphicsDevice::Clear(ColorRGB color)
{
	Vector3 vcolor = color.ToVector3();
	glClearColor(vcolor.m_fX, vcolor.m_fY, vcolor.m_fZ, 1.0f );

	/* Clear The Screen And The Depth Buffer */
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

}

void GraphicsDevice::Clear(ColorRGBA color)
{
	Vector4 vcolor = color.ToVector4();
	glClearColor(vcolor.m_fX, vcolor.m_fY, vcolor.m_fZ, vcolor.m_fW );

	/* Clear The Screen And The Depth Buffer */
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

}